package com.zyht.bank.wechat.controller;

import java.util.Calendar;
import java.util.GregorianCalendar;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import com.wx.entity.WxFansUser;
import com.wx.model.dictionary.Constant;
import com.wx.util.PhoneUtils;
import com.zyht.bank.wechat.utils.sms.SMSUtil;
import com.zyht.bank.wechat.utils.sms.SMSVo;
import com.zyht.common.AbsPrintBaseController;
import com.zyht.common.bean.PropertiesUtilBean.PropertiesUtils;
import com.zyht.redis.service.RedisService;
import com.zyht.wechat.framework.Oauth;
import com.zyht.wechat.framework.constant.ConfigConstants;

/**
 * 描述：获取手机验证码<br>
 * 作者：ruibo <br>
 * 修改日期：2017年2月15日-下午5:07:17 <br>
 */

@RequestMapping("anon/phone/vcode")
@Controller
public class PhoneValidationCodeController extends AbsPrintBaseController {

	public static final String PHONE_VALIDATION_CODE_REDIS_KEY_PRE = PhoneValidationCodeController.class.getName()
			.concat(".");

	private static final String CHECK_TIMES_IN_TWO_MIN_KEY = "check_times_in_two_min_key";

	private static final String CHECK_TOTAL_TIMES_IN_ONE_DAY_KEY = "check_total_times_in_one_day_key";

	private static final String CHECK_IP_TIMES_IN_ONE_MIN_KEY = "check_ip_times_in_one_min_key";

	private static final String CHECK_IP_PUNISHMENT_TIME_KEY = "check_ip_punishment_time_key";

	private static final String CHECK_CURRENT_TIME_PLUS_ONE_MIN_KEY = "check_current_time_plus_one_min_key";

	private static final int TWO_MIN_TIMES_INT = 1;

	private static final int ONE_DAY_TIMES_INT = 10;

//	private final String STATICCHARSTRING = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
	private final String STATICCHARSTRING = "1234567890";

	@Resource
	private RedisService redisService;

	@Oauth
	@RequestMapping("{phoneNo}")
	public void getValidateCodeByPhoneNO(@PathVariable String phoneNo, HttpServletRequest request,
			HttpServletResponse response) {
		if (!PhoneUtils.isMobile(phoneNo)) {
			writeJson(response, "{\"state\":400,\"msg\":\"请输入正确的手机号！\"}");
			return;
		}

		// 获取用户信息
		WxFansUser wxFansUser = (WxFansUser) request.getSession()
				.getAttribute(Constant.CURRENT_USER_FANINFO_FROM_EVENT_VIEW);
		wxFansUser.getId();

		// ip限制(单IP一分钟只能发200条, 超限制, 封5分钟)
		String current_ip = request.getRemoteAddr();
		String ipLimitTimesKey = CHECK_IP_TIMES_IN_ONE_MIN_KEY.concat(current_ip);
		String ipPunishedTimesKey = CHECK_IP_PUNISHMENT_TIME_KEY.concat(current_ip);
		String ipPlusOneMinKey = CHECK_CURRENT_TIME_PLUS_ONE_MIN_KEY.concat(current_ip);
		String ipLimitTimesStr = this.redisService.get(ipLimitTimesKey);
		String ipPunishedTimesStr = this.redisService.get(ipPunishedTimesKey);
		if (!StringUtils.isEmpty(ipPunishedTimesStr)) {
			writeJson(response, "{\"state\":400,\"msg\":\"该网段请求次数超限,请 5 分钟后再试\"}");
			return;
		}
		int limitTimes = 0;
		if (StringUtils.isEmpty(ipLimitTimesStr)) {
			long currentTimeMillis = System.currentTimeMillis();
			String currentTimePlusOneMin = (currentTimeMillis + 60l * 1000) + "";
			this.redisService.setEx(ipLimitTimesKey, 60, "0");
			this.redisService.setEx(ipPlusOneMinKey, 60, currentTimePlusOneMin);
		} else {
			limitTimes = Integer.parseInt(ipLimitTimesStr);
			if (limitTimes >= 200) {
				this.redisService.setEx(ipPunishedTimesKey, 300, "0");
				writeJson(response, "{\"state\":400,\"msg\":\"该网段请求次数超限,请 5 分钟后再试\"}");
				return;
			}
		}

		// 手机号限制 (同一手机号一天限10条,一分钟内限1条)
		String totalTimesKey = CHECK_TOTAL_TIMES_IN_ONE_DAY_KEY.concat(phoneNo);
		String twoMinTimesKey = CHECK_TIMES_IN_TWO_MIN_KEY.concat(phoneNo);
		String totalTimesStr = this.redisService.get(totalTimesKey);
		String twoMinTimesStr = this.redisService.get(twoMinTimesKey);
		if (StringUtils.isEmpty(twoMinTimesStr)) {
			this.redisService.set(twoMinTimesKey, "0");
			twoMinTimesStr = "0";
		}
		if (StringUtils.isEmpty(totalTimesStr)) {
			this.redisService.set(totalTimesKey, "0");
			this.redisService.set(twoMinTimesKey, "0");
			twoMinTimesStr = "0";
			totalTimesStr = "0";
		}
		int totalTimesVal = Integer.parseInt(totalTimesStr);
		int twoMinTimesVal = Integer.parseInt(twoMinTimesStr);
		if (totalTimesVal >= ONE_DAY_TIMES_INT) {
			// 当天次数超限制
			writeJson(response, "{\"state\":400,\"msg\":\"您今天短信次数已达上限(10次),请明天再试\"}");
			return;
		}
		if (twoMinTimesVal >= TWO_MIN_TIMES_INT) {
			// 两分钟内发过短信
			writeJson(response, "{\"state\":400,\"msg\":\"请2分钟后再试\"}");
			return;
		}

		String validationCode = RandomStringUtils.random(4, STATICCHARSTRING);
		logger.debug("手机号为[" + phoneNo + "]的验证码是【" + validationCode + "】");
		if (sendValidationCode(phoneNo, validationCode)) {
			this.redisService.setEx(PHONE_VALIDATION_CODE_REDIS_KEY_PRE.concat(phoneNo), 120, validationCode);

			// 做+1操作
			twoMinTimesVal++;
			totalTimesVal++;
			limitTimes++;
			long currentTimeMillis = System.currentTimeMillis();
			String currentTimePlusOneMin = this.redisService.get(ipPlusOneMinKey);
			if (!StringUtils.isEmpty(currentTimePlusOneMin)) {
				long currentTimePlusOneMinL = Long.parseLong(currentTimePlusOneMin);
				int exTimeMills = (int) (currentTimePlusOneMinL - currentTimeMillis);
				int exTimesSeconds = exTimeMills / 1000;
				if (exTimesSeconds > 0) {
					this.redisService.setEx(ipLimitTimesKey, exTimesSeconds, limitTimes + "");
				} else {
					this.redisService.del(ipLimitTimesKey);
				}
			}
			this.redisService.setEx(twoMinTimesKey, 120, twoMinTimesVal + "");
			long nowVal = System.currentTimeMillis();
			Calendar calendar = new GregorianCalendar();
			calendar.set(Calendar.HOUR_OF_DAY, 0);
			calendar.set(Calendar.MINUTE, 0);
			calendar.set(Calendar.SECOND, 0);
			calendar.add(Calendar.DATE, 1);
			long tomorowVal = calendar.getTimeInMillis();
			this.redisService.setEx(totalTimesKey, (tomorowVal - nowVal) / 1000, totalTimesVal + "");

			writeJson(response, "{\"state\":200}");
		} else
			writeJson(response, "{\"state\":400,\"msg\":\"请求超时！\"}");
	}

	private final boolean sendValidationCode(String phoneNo, String code) {
		SMSVo smsVo = new SMSVo();
		smsVo.setPort(PropertiesUtils.getConfig(ConfigConstants.SMS_PORT));
		smsVo.setPwd(PropertiesUtils.getConfig(ConfigConstants.SMS_PWD));
		smsVo.setIp(PropertiesUtils.getConfig(ConfigConstants.SMS_IP));
		smsVo.setUserid(PropertiesUtils.getConfig(ConfigConstants.SMS_USERID));
		smsVo.setUserid(PropertiesUtils.getConfig(ConfigConstants.SMS_USERID));
		smsVo.setSvrtype(PropertiesUtils.getConfig(ConfigConstants.SMS_SVRTYPE));
		smsVo.setMobile(phoneNo);
		smsVo.setContent("您的手机验证码是【" + code + "】，有效时间为2分钟，为了您的账户安全，请勿泄露给他人！");
		return SMSUtil.singleSend(smsVo);
	}
}
